﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Model
{
    [ObjectEvent]
    public class OpcodeTypeComponentEvent : ObjectEvent<OpcodeTypeComponent>, IAwake
    {
        public void Awake()
        {
            this.Get().Awake();
        }
    }


    /// <summary>
    /// 所有消息类型扫描组件
    /// </summary>
    public class OpcodeTypeComponent : Component
    {
        /// <summary>
        /// 操作码对应的类型
        /// </summary>
        private Dictionary<Opcode, Type> opcodeType;

        /// <summary>
        /// 类型对应的特性
        /// </summary>
        private Dictionary<Type, MessageAttribute> messageOpcode;

        public void Awake()
        {
            this.Load();
        }

        public void Load()
        {
            this.opcodeType = new Dictionary<Opcode, Type>();
            this.messageOpcode = new Dictionary<Type, MessageAttribute>();

            List<Type> types = DllHelper.GetAllTypes();

            foreach (Type type in types)
            {
                object[] attrs = type.GetCustomAttributes(typeof(MessageAttribute), false);
                if (attrs.Length == 0)
                    continue;

                MessageAttribute messageAttribute = attrs[0] as MessageAttribute;
                this.messageOpcode[type] = messageAttribute;
                this.opcodeType[messageAttribute.Opcode] = type;
            }
        }

        public Opcode GetOpcode(Type type)
        {
            if(!this.messageOpcode.TryGetValue(type,out MessageAttribute messageAttribute))
            {
                throw new Exception($"查找Opcode失败: {type.Name}");
            }
            return messageAttribute.Opcode;
        }

        public Type GetType(Opcode opcode)
        {
            if(!this.opcodeType.TryGetValue(opcode,out Type type))
            {
                throw new Exception($"查找Type失败:{opcode}");
            }
            return type;
        }

        public override void Dispose()
        {
            if (this.Id == 0) return;

            base.Dispose();
        }
    }
}
